import Dep from './Dep.js'
import {getVal} from "../utils.js";
import {queueWatcher} from './nextTick.js'

const stack = []

function pushStack (watcher){
    if(!stack.find(wa => wa.id === watcher.id)) {
        // 不存在
        Dep.target = watcher
        stack.push(watcher)
    }
}

function popStack(){
    stack.pop()
    Dep.target = stack[stack.length - 1]
}

let index = 0

class Watcher{
    constructor(vm , experOrFn, cb, options){
        this.$vm = vm
        this.deps = []
        this.id = index++
        this.cb = cb
        if(typeof experOrFn === 'function'){
            this.getter = experOrFn
        }else{
            this.getter = ()=>{
                return getVal(vm, experOrFn) // 第二个参数如果是表达式，证明是 作为 $watche使用的， 此时返回对应的被监听的值
            }
        }
        this.oldValue = this.get() // 存储老值
    }
    get(){
        pushStack(this)
        let value = this.getter()
        popStack()
        return value;
    }
    addDep(dep){
        this.deps.push(dep)
        dep.addSubs(this)
    }
    update(){
        queueWatcher(this)
    }
    run(){
        let newVal = this.get();
        if(this.oldValue !== newVal){
            this.cb(newVal, this.oldValue)
            this.oldValue = newVal
        }
    }
}


export default Watcher
